﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Threading;
using HandyControl.Data;
using HandyControl.Tools;

namespace HandyControl.Controls;

public sealed class Notification : System.Windows.Window
{
    private const int WaitTime = 6;

    /// <summary>
    ///     计数
    /// </summary>
    private int _tickCount;

    /// <summary>
    ///     关闭计时器
    /// </summary>
    private DispatcherTimer _timerClose;

    private ShowAnimation ShowAnimation { get; set; }

    private bool _shouldBeClosed;

    public Notification()
    {
        WindowStyle = WindowStyle.None;
        AllowsTransparency = true;
    }

    public static Notification Show(object content, ShowAnimation showAnimation = ShowAnimation.None, bool staysOpen = false)
    {
        var notification = new Notification
        {
            Content = content,
            Opacity = 0,
            ShowAnimation = showAnimation
        };

        notification.Show();

        var desktopWorkingArea = SystemParameters.WorkArea;
        var leftMax = desktopWorkingArea.Width - notification.ActualWidth;
        var topMax = desktopWorkingArea.Height - notification.ActualHeight;

        switch (showAnimation)
        {
            case ShowAnimation.None:
                notification.Opacity = 1;
                notification.Left = leftMax;
                notification.Top = topMax;
                break;
            case ShowAnimation.HorizontalMove:
                notification.Opacity = 1;
                notification.Left = desktopWorkingArea.Width;
                notification.Top = topMax;
                notification.BeginAnimation(LeftProperty, AnimationHelper.CreateAnimation(leftMax));
                break;
            case ShowAnimation.VerticalMove:
                notification.Opacity = 1;
                notification.Left = leftMax;
                notification.Top = desktopWorkingArea.Height;
                notification.BeginAnimation(TopProperty, AnimationHelper.CreateAnimation(topMax));
                break;
            case ShowAnimation.Fade:
                notification.Left = leftMax;
                notification.Top = topMax;
                notification.BeginAnimation(OpacityProperty, AnimationHelper.CreateAnimation(1));
                break;
            default:
                notification.Opacity = 1;
                notification.Left = leftMax;
                notification.Top = topMax;
                break;
        }

        if (!staysOpen) notification.StartTimer();

        return notification;
    }

    protected override void OnClosing(CancelEventArgs e)
    {
        base.OnClosing(e);

        if (_shouldBeClosed)
        {
            return;
        }
        var desktopWorkingArea = SystemParameters.WorkArea;

        switch (ShowAnimation)
        {
            case ShowAnimation.None:
                break;
            case ShowAnimation.HorizontalMove:
                {
                    var animation = AnimationHelper.CreateAnimation(desktopWorkingArea.Width);
                    animation.Completed += Animation_Completed;
                    BeginAnimation(LeftProperty, animation);
                    e.Cancel = true;
                    _shouldBeClosed = true;
                }
                break;
            case ShowAnimation.VerticalMove:
                {
                    var animation = AnimationHelper.CreateAnimation(desktopWorkingArea.Height);
                    animation.Completed += Animation_Completed;
                    BeginAnimation(TopProperty, animation);
                    e.Cancel = true;
                    _shouldBeClosed = true;
                }
                break;
            case ShowAnimation.Fade:
                {
                    var animation = AnimationHelper.CreateAnimation(0);
                    animation.Completed += Animation_Completed;
                    BeginAnimation(OpacityProperty, animation);
                    e.Cancel = true;
                    _shouldBeClosed = true;
                }
                break;
        }
    }

    private void Animation_Completed(object sender, EventArgs e) => Close();

    /// <summary>
    ///     开始计时器
    /// </summary>
    private void StartTimer()
    {
        _timerClose = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(1)
        };
        _timerClose.Tick += delegate
        {
            if (IsMouseOver)
            {
                _tickCount = 0;
                return;
            }

            _tickCount++;
            if (_tickCount >= WaitTime) Close();
        };
        _timerClose.Start();
    }
}
